package com.ecoolex.ying.space.admin.graphql;

import static com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type.Admin;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.alibaba.fastjson.JSONArray;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.ying.space.admin.core.AdminConstant;
import com.ecoolex.ying.space.entity.EstateProjectActivity;
import com.ecoolex.ying.space.entity.EstateProjectActivity.Column;
import com.ecoolex.ying.space.entity.EstateProjectActivityGoods;
import com.ecoolex.ying.space.entity.EstateProjectActivityGoodsCategory;
import com.ecoolex.ying.space.entity.EstateProjectActivityHouseModel;
import com.ecoolex.ying.space.entity.EstateProjectActivityHouseModelItems;
import com.ecoolex.ying.space.entity.EstateProjectActivityHouseModelItemsGoods;
import com.ecoolex.ying.space.pojo.AddEstateProjectActivityDTO;
import com.ecoolex.ying.space.pojo.AddEstateProjectActivityHouseModelDTO;
import com.ecoolex.ying.space.pojo.AddEstateProjectActivityHouseModelItemsDTO;
import com.ecoolex.ying.space.pojo.EditEstateProjectActivityDTO;
import com.ecoolex.ying.space.pojo.EditEstateProjectActivityHouseModelDTO;
import com.ecoolex.ying.space.ws.EstateProjectActivityService;
import com.google.common.collect.Lists;

@GraphQL2Module(type = Admin, description = "地产项目活动管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY, key = EstateProjectActivityGraphql.AUTH, name = "地产项目活动管理")
public class EstateProjectActivityGraphql {

	public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-ESTATE-PROJECT-ACTIVITY";
	
	private static final String AUTH_ADD = AUTH + "-ADD";
	
	private static final String AUTH_MODEL_ADD = AUTH + "-MODEL-ADD";
	
	private static final String AUTH_EDIT = AUTH + "-EDIT";
	
	private static final String AUTH_MODEL_EDIT = AUTH + "-MODEL-EDIT";
	
	private static final String AUTH_DEL = AUTH + "-DEL";
	
	private static final String AUTH_GET = AUTH + "-GET";
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	private static final String AUTH_MODEL_DEL = AUTH + "-MODEL-DEL";
	
	private static final String AUTH_MODEL_GET = AUTH + "-MODEL-GET";
	
	private static final String AUTH_MODEL_QUERY = AUTH + "-MODEL-QUERY";
	
	private static final String AUTH_ONLINE = AUTH + "-ONLINE";
	
	private static final String AUTH_OFFLINE = AUTH + "-OFFLINE";
	
	@Autowired
    private StorageService storageService;
	
	@Reference
	private EstateProjectActivityService service;
	
	@TypeField(type = EstateProjectActivity.class, field = "canDelete", description = "能删除")
	public boolean canDelete(@Source EstateProjectActivity source, AdminMemberAuthority user) {
		return user.auth(AUTH_DEL);
	}
	
	@TypeField(type = EstateProjectActivity.class, field = "canOnline", description = "能上线")
	public boolean canOnline(@Source EstateProjectActivity source, AdminMemberAuthority user) {
		return user.auth(AUTH_ONLINE) && !source.getOnline();
	}
	
	@TypeField(type = EstateProjectActivity.class, field = "canOffline", description = "能下线")
	public boolean canOffline(@Source EstateProjectActivity source, AdminMemberAuthority user) {
		return user.auth(AUTH_OFFLINE) && source.getOnline();
	}
	
	@TypeField(type = EstateProjectActivity.class, field = "image", description = "地产项目展示图")
    public StorageInfo image(@Source EstateProjectActivity source) {
        return storageService.get(source.getImage());
    }
	
	@TypeField(type = EstateProjectActivityHouseModel.class, field = "coverImage", description = "地产项目户型方案封面图")
    public StorageInfo coverImage(@Source EstateProjectActivityHouseModel source) {
        return storageService.get(source.getCoverImage());
    }
	
	@TypeField(type = EstateProjectActivityHouseModel.class, field = "modelImages", description = "地产项目户型方案展示图")
    public StorageInfo modelImages(@Source EstateProjectActivityHouseModel source) {
        return storageService.get(source.getImages());
    }
	
	@TypeField(type = EstateProjectActivityHouseModelItems.class, field = "jumpGoodsImage", description = "地产项目户型方案条目跳转图片")
    public StorageInfo itemsJumpGoodsImage(@Source EstateProjectActivityHouseModelItems source) {
		return storageService.get(source.getJumpGoodsImage());
    }
	
	@TypeField(type = EstateProjectActivityHouseModelItems.class, field = "itemsImages", description = "地产项目户型方案条目图片")
    public List<StorageInfo> itemsImages(@Source EstateProjectActivityHouseModelItems source) {
		String images = source.getImages();
		if(Check.notNull(images)) {
			JSONArray jsonArray = JSONArray.parseArray(images);
			List<String> list = jsonArray.toJavaList(String.class);
			return list.stream().map(storageId -> storageService.get(storageId)).collect(Collectors.toList());
		}
		return null;
    }
	
	@TypeField(type = StorageInfo.class, field = "houseModeItemsGoods", description = "方案条目图片购物")
	public List<EstateProjectActivityHouseModelItemsGoods> itemsGoods(@Source StorageInfo source){
		return service.listByStorageId(source.getStorageId());
	}
	
	@TypeField(type = EstateProjectActivityHouseModelItemsGoods.class,field = "estateProjectActivityGoods",description = "活动商品")
	public EstateProjectActivityGoods estateProjectActivityGoods(@Source EstateProjectActivityHouseModelItemsGoods source) {
		return service.getEstateProjectActivityGoods(source.getActivityGoodsId());
	}
	
	@TypeField(type = EstateProjectActivity.class, field = "categoryList", description = "地产项目活动绑定分类列表")
	public Pagination<EstateProjectActivityGoodsCategory> categoryList(@Source EstateProjectActivity source,@NonNull Boolean online,@NonNull Integer level,@NonNull Sorting[] sorts,@NonNull Page page){
		return service.queryEstateProjectActivityGoodsCategory(source.getProjectId(), null,online, level, sorts, page);
	}
	
	@TypeField(type = EstateProjectActivity.class, field = "modelList", description = "地产项目活动户型方案列表")
	public List<EstateProjectActivityHouseModel> modelList(@Source EstateProjectActivity source){
		return service.modelList(source.getProjectId());
	}
	
	@TypeField(type = EstateProjectActivityHouseModel.class, field = "estateProjectActivity", description = "地产项目活动户型方案所属项目")
	public EstateProjectActivity estateProjectActivity(@Source EstateProjectActivityHouseModel source) {
		return service.get(source.getProjectId());
	}
	
	@TypeField(type = EstateProjectActivityHouseModel.class, field = "itemsList", description = "地产项目活动户型方案条目列表")
	public List<EstateProjectActivityHouseModelItems> itemsList(@Source EstateProjectActivityHouseModel source){
		return service.itemsList(source.getModelId());
	}
	
	@TypeField(type = EstateProjectActivityHouseModelItems.class, field = "estateProjectActivityGoodsList", description = "地产项目活动方案条目关联商品列表")
	public List<EstateProjectActivityGoods> estateProjectActivityGoodsList(@Source EstateProjectActivityHouseModelItems source) {
		
		return service.listByItemId(source.getItemId());
	}
	
	@MutationField(field = "uploadEstateProjectActivityImage", description = { "上传地产项目展示图" })
    public StorageInfo uploadEstateProjectActivityImage(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("EstateProjectActivity", "Image");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }
	
	@MutationField(field = "uploadEstateProjectActivityHouseModelCoverImage", description = { "上传地产项目户型方案封面图" })
    public StorageInfo uploadEstateProjectActivityHouseModelCoverImage(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("EstateProjectActivityHouseModel", "CoverImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }
	
	@MutationField(field = "uploadEstateProjectActivityHouseModelImages", description = { "上传地产项目户型方案展示图" })
    public StorageInfo uploadEstateProjectActivityHouseModelImages(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("EstateProjectActivityHouseModel", "Images");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }
	
	@MutationField(field = "uploadEstateProjectActivityHouseModelItemsImages", description = { "上传地产项目户型方案条目图片" })
    public StorageInfo uploadEstateProjectActivityHouseModelItemsImages(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("EstateProjectActivityHouseModelItems", "Images");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }
	
	@MutationField(field = "uploadEstateProjectActivityHouseModelItemsJumpGoodsImage", description = { "上传地产项目户型方案条目跳转图片" })
    public StorageInfo uploadEstateProjectActivityHouseModelItemsJumpGoodsImage(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("EstateProjectActivityHouseModelItems", "JumpGoodsImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
    }
	
	@QueryField(field = "estateProjectActivity" , description = "地产项目详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "地产项目详情")
	public EstateProjectActivity get(@NonNull Integer projectId,AdminMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return service.get(projectId);
	}
	
	@QueryField(field = "estateProjectActivityList" , description = "地产项目列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "地产项目列表")
	public Pagination<EstateProjectActivity> query(Boolean online,@NonNull Sorting[] sorts,@NonNull Page page,AdminMemberAuthority user) {
		user.assertAuth(AUTH_QUERY);
		return service.query(online,sorts, page);
	}
	
	@MutationField(field = "addEstateProjectActivity", description = "添加地产项目")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加地产项目")
	public EstateProjectActivity add(@NonNull AddEstateProjectActivityDTO activityDTO,AdminMemberAuthority user) {
		user.assertAuth(AUTH_ADD);
		return service.add(activityDTO, user.userName());
	}
	
	@MutationField(field = "editEstateProjectActivity", description = "编辑地产项目")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑地产项目")
	public EstateProjectActivity edit(@NonNull EditEstateProjectActivityDTO activityDTO,AdminMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		EstateProjectActivity old = service.get(activityDTO.getProjectId());
		Assert.isTrue(Check.notNull(old),ResultCode.VERIFY.build(1), "地产项目活动Id={}不存在",activityDTO.getProjectId());
		BeanUtil.copy(activityDTO,
            old,
            Lists.newArrayList(
            		Column.online,
                    Column.deleted,
                    Column.createUser,
                    Column.createTime).stream().map(Column::getJavaProperty).toArray(String[]::new));
		return service.edit(old, user.userName());
	}
	
	@MutationField(field = "delEstateProjectActivity", description = "删除地产项目活动")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除地产项目活动")
	public boolean delete(@NonNull Integer projectId,AdminMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		EstateProjectActivity old = service.get(projectId);
		Assert.isTrue(Check.notNull(old),ResultCode.VERIFY.build(1), "地产项目活动Id={}不存在",projectId);
		service.delete(old, user.userName());
		return true;
	}
	
	@MutationField(field = "onlineEstateProjectActivity", description = "上线地产项目活动")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ONLINE, name = "上线地产项目活动")
	public boolean online(@NonNull Integer projectId,AdminMemberAuthority user) {
		user.assertAuth(AUTH_ONLINE);
		EstateProjectActivity old = service.get(projectId);
		Assert.isTrue(Check.notNull(old),ResultCode.VERIFY.build(1), "地产项目活动Id={}不存在",projectId);
		service.online(old, user.userName());
		return true;
	}
	
	@MutationField(field = "offlineEstateProjectActivity", description = "下线地产项目活动")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_OFFLINE, name = "下线地产项目活动")
	public boolean offline(@NonNull Integer projectId,AdminMemberAuthority user) {
		user.assertAuth(AUTH_OFFLINE);
		EstateProjectActivity old = service.get(projectId);
		Assert.isTrue(Check.notNull(old),ResultCode.VERIFY.build(1), "地产项目活动Id={}不存在",projectId);
		service.offline(old, user.userName());
		return true;
	}
	
	@QueryField(field = "estateProjectActivityHouseModel" , description = "地产项目户型方案详情")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_MODEL_GET, name = "地产项目户型方案详情")
	public EstateProjectActivityHouseModel getEstateProjectActivityHouseModel(@NonNull Integer modelId,AdminMemberAuthority user) {
		user.assertAuth(AUTH_MODEL_GET);
		return service.getEstateProjectActivityHouseModel(modelId);
	}
	
	@QueryField(field = "estateProjectActivityHouseModelList" , description = "地产项目户型方案列表")
	@AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_MODEL_QUERY, name = "地产项目户型方案列表")
	public Pagination<EstateProjectActivityHouseModel> queryEstateProjectActivityHouseModel(Integer projectId,@NonNull Sorting[] sorts,@NonNull Page page,AdminMemberAuthority user) {
		user.assertAuth(AUTH_MODEL_QUERY);
		return service.modelList(projectId, sorts, page);
	}
	
	@MutationField(field = "addEstateProjectActivityHouseModel", description = "添加地产项目活动方案")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_MODEL_ADD, name = "添加地产项目活动方案")
	public EstateProjectActivityHouseModel addModel(@NonNull AddEstateProjectActivityHouseModelDTO record,
									      @NonNull List<AddEstateProjectActivityHouseModelItemsDTO> itemsDTOList, 
									      AdminMemberAuthority user) {
		user.assertAuth(AUTH_MODEL_ADD);
		return service.addModel(record, itemsDTOList, user.userName());
	}
	
	@MutationField(field = "editEstateProjectActivityHouseModel", description = "编辑地产项目活动方案")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_MODEL_EDIT, name = "编辑地产项目活动方案")
	public EstateProjectActivityHouseModel editModel(@NonNull EditEstateProjectActivityHouseModelDTO record,
									       @NonNull List<AddEstateProjectActivityHouseModelItemsDTO> itemsDTOList, 
									       AdminMemberAuthority user) {
		
		user.assertAuth(AUTH_MODEL_EDIT);
		EstateProjectActivityHouseModel old = service.getEstateProjectActivityHouseModel(record.getModelId());
		Assert.isTrue(Check.notNull(old),ResultCode.VERIFY.build(1), "地产项目活动方案Id={}不存在",record.getModelId());
		BeanUtil.copy(record,
            old,
            Lists.newArrayList(
            	com.ecoolex.ying.space.entity.EstateProjectActivityHouseModel.Column.deleted,
            	com.ecoolex.ying.space.entity.EstateProjectActivityHouseModel.Column.createUser,
            	com.ecoolex.ying.space.entity.EstateProjectActivityHouseModel.Column.createTime).stream().map(com.ecoolex.ying.space.entity.EstateProjectActivityHouseModel.Column::getJavaProperty).toArray(String[]::new));
		return service.editModel(old, itemsDTOList, user.userName());
	}
	
	@MutationField(field = "delEstateProjectActivityHouseModel", description = "删除地产项目活动户型方案")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_MODEL_DEL, name = "删除地产项目活动户型方案")
	public boolean deleteModel(@NonNull Integer modelId,AdminMemberAuthority user) {
		user.assertAuth(AUTH_MODEL_DEL);
		EstateProjectActivityHouseModel model = service.getEstateProjectActivityHouseModel(modelId);
		Assert.isTrue(Check.notNull(model),ResultCode.VERIFY.build(1), "地产项目活动方案Id={}不存在",model);
		service.deleteEstateProjectActivityHouseModel(model, user.userName());
		return true;
	}
	
}
